#include <stdio.h>
#include <inttypes.h>
#include <malloc.h>

static char *fgetstr(char *buffer, size_t size, FILE *f)
{
	int i = 0;

	do {
		buffer[i] = fgetc(f);
	} while (i < (size - 1) && buffer[i++] != 0);

	return buffer;
}

int convert_to_html(char *input_file, char *output_file)
{
	FILE *puz_file, *html_file;
	int w, h;
	int x, y, z;
	int clue_count;
	char buffer[4096];
	char **grid;
	int across_clues, down_clues;

	puz_file = fopen(input_file, "r");
	if (puz_file == NULL) {
		perror("fopen");
		return 1;
	}

	html_file = fopen(output_file, "w");
	if (html_file == NULL) {
		perror("fopen");
		return 1;
	}

	fseek(puz_file, 0x2C, SEEK_SET);
	w = fgetc(puz_file);
	h = fgetc(puz_file);

	// Start HTML

	fprintf(html_file,"<html>\n<head>\n");
	fprintf(html_file,"<title>Converted Puzzle: %s</title>\n", input_file);
	
	fprintf(html_file,"<style type=\"text/css\">\n");
	fprintf(html_file,"	body\n	{\n		font: 10px arial;\n		text-align: left;\n		text-align: center;\n	}\n\n");
	fprintf(html_file,"	div.header\n	{\n		text-align: center;\n	}\n\n");
	fprintf(html_file,"	div.clue_column\n	{\n	       width: 25%%;\n		padding: 0px;\n		float: left;\n		text-align: left;\n		}\n\n");
	fprintf(html_file,"	h1\n	{\n		font: bold 14px arial;\n	}\n\n");	
	fprintf(html_file,"	h2\n	{\n		width: 50%%;\n		margin-top:0px;\n	font: bold 12px arial;\n		text-align: center;\n		float: left;\n	}\n\n");
	fprintf(html_file,"	ol\n	{\n		margin: 0px;\n		list-style-position: outside;\n	}\n\n");
	fprintf(html_file,"	li\n	{\n		padding: 0px;\n		margin: 0px;\n	}\n\n");	
	fprintf(html_file,"	table.crossword\n	{\n		border-collapse: collapse;\n		background-color: transparent;\n		margin-top:10px;\n		margin-bottom:10px;\n		margin-left: auto;\n		margin-right: auto;\n		position: relative;\n	}\n\n");
	fprintf(html_file,"	table.crossword td\n	{\n		width: 25px;\n		height: 25px;\n		border: 1px solid black;\n		padding: 1px;\n		margin: 0px;\n		background-color: transparent;\n		font: 8px arial;\n		vertical-align: top;\n	}\n\n");	
	fprintf(html_file,"	table.crossword td#filled_cell\n	{\n		padding: 0px;\n	}\n\n");
	fprintf(html_file,"	img.crossword_cell\n	{\n		width: 100%%;\n		height: 100%%;\n		margin: 0px;\n		padding: 0px;\n	}\n");
	fprintf(html_file,"</style>\n</head>\n<body>\n");

	// Parse the puzzle file

	//printf("Size: %dx%d\n", w, h);
	fseek(puz_file, 0x34, SEEK_SET);

	grid = malloc(sizeof(char *) * h);
	for (y = 0; y < h; y++)
		grid[y] = malloc(sizeof(char) * w);

	// Parse puzzle layout
	for (y = 0; y < h; y++) {
		for (x = 0; x < h; x++) {
			char ch;
			ch = fgetc(puz_file);
		}
	}

	// Parse answers
	for (y = 0; y < h; y++) {
		for (x = 0; x < h; x++) {
			grid[y][x] = fgetc(puz_file);
		}
	}

	// Print out title information
	fprintf(html_file,"<div class=\"header\">\n");

	// Title
	fgetstr(buffer, sizeof(buffer), puz_file);
	fprintf(html_file,"<h1>%s</h1>\n", buffer);

	// Author
	fgetstr(buffer, sizeof(buffer), puz_file);
	fprintf(html_file,"Author: %s<br/>\n", buffer);

	// Copyright
	fgetstr(buffer, sizeof(buffer), puz_file);
	fprintf(html_file,"%s\n</div>\n\n", buffer);

	// Print out crossword table

	fprintf(html_file,"<table class=\"crossword\">\n");
	clue_count = 1;
	for (y = 0; y < h; y++) {
		fprintf(html_file,"<tr>\n");
		
		for (x = 0; x < h; x++) {
			if (grid[y][x] == '.') {
				fprintf(html_file,"	<td id=\"filled_cell\"><img class=\"crossword_cell\" src=\"\"></td>\n");
			} else if (x == 0 || y == 0 || grid[y][x-1] == '.' || grid[y-1][x] == '.') {
				fprintf(html_file,"	<td>%i</td>\n", clue_count);
				clue_count++;
			} else {
				fprintf(html_file,"	<td></td>\n");
			}
		}

		fprintf(html_file,"</tr>\n");
		
	}
	fprintf(html_file,"</table>\n");	

	across_clues = 0;
	for (y = 0; y < h; y++) {
		int in_answer = 0;

		for (x = 0; x < w; x++) {
			if (in_answer) {
				if (grid[y][x] == '.')
					in_answer = 0;
				else if (in_answer == 1) {
					in_answer = 2;
					across_clues++;
				}
			} else {
				if (grid[y][x] == '-')
					in_answer = 1;
			}
		}
	}

	down_clues = 0;
	for (x = 0; x < w; x++) {
		int in_answer = 0;

		for (y = 0; y < h; y++) {
			if (in_answer) {
				if (grid[y][x] == '.')
					in_answer = 0;
				else if (in_answer == 1) {
					in_answer = 2;
					down_clues++;
				}
			} else {
				if (grid[y][x] == '-')
					in_answer = 1;
			}
		}
	}

	// Print out clues

	fprintf(html_file,"<h2>Across</h2>\n<h2>Down</h2>\n\n");

	fprintf(html_file,"<div class=\"clue_column\">\n");
	z = 0;
	clue_count = 0;
	for (y = 0; y < h; y++) {
		for (x = 0; x < h; x++) {
			if (!(grid[y][x] == '.') && (x == 0 || y == 0 || grid[y][x-1] == '.' || grid[y-1][x] == '.')) {
				z++;
				if (x == 0 || grid[y][x-1] == '.') {
					fgetstr(buffer, sizeof(buffer), puz_file);
					clue_count++;
					if (clue_count == across_clues/2 + 2) {
						fprintf(html_file,"</div>\n<div class=\"clue_column\">\n");
					}
					fprintf(html_file,"<ol start=\"%i\"><li>%s</li></ol>\n", z, buffer);
				}
			}
		}		
	}
	fprintf(html_file,"</div>\n\n");

	fprintf(html_file,"<div class=\"clue_column\">\n");
	z = 0;
	clue_count = 0;
	for (y = 0; y < h; y++) {
		for (x = 0; x < h; x++) {
			if (!(grid[y][x] == '.') && (x == 0 || y == 0 || grid[y][x-1] == '.' || grid[y-1][x] == '.')) {
				z++;
				if (y == 0 || grid[y-1][x] == '.') {
					fgetstr(buffer, sizeof(buffer), puz_file);
					clue_count++;
					if (clue_count == down_clues/2 + 2) {
						fprintf(html_file,"</div>\n<div class=\"clue_column\">\n");
					}
					fprintf(html_file,"<ol start=\"%i\"><li>%s</li></ol>\n", z, buffer);
				}
			}
		}		
	}
	fprintf(html_file,"</div>\n\n");

	/*fgetstr(buffer, sizeof(buffer), puz_file);
	  printf("About Author: %s\n", buffer);*/

	fprintf(html_file,"</body>\n</html>\n");

	fclose(puz_file);
	fclose(html_file);

	return 0;
}

int main(int argc, char **argv)
{
	int return_value;

	if (argc != 2) {
		printf("Usage: %s FILE\n", argv[0]);
		return 1;
	}

	return_value = convert_to_html(argv[1], "puzzle.html");

	return return_value;
}
